/*
	Copyright (c) 2010 <copyright holders>
	This source code is licensed under The MIT License,
	see the file LICENSE for details.
	*/

#ifndef HELPDEFS_HPP
#define HELPDEFS_HPP

#include <boost/lexical_cast.hpp>
#include <string>
#include <OGRE/OgreException.h>
#include <OGRE/OgreLog.h>
#include <string>

//idea for this macro borrowed from google
#define HIDE_EVIL_CONSTRUCTORS(t) \
    t(const t&); \
    void operator=(const t&)

#define STRING_CAST(x)  (boost::lexical_cast<std::string>(x))

//macros for declaring members that are read only publically (only use in highly coherent classes)
#define DECLARE_READ_VAR(type, name)  \
    public: \
    type get##name() const { return name##_; } \
    private: \
    type name##_
#define DECLARE_READ_REF(type, name)  \
    public: \
    const type & get##name() const { return name##_; } \
    private: \
    type name##_

//standard macro producing a string literal containing file and line, like "Game.cpp:27"
#define STRINGIFY(x) #x
#define TOSTRING(x) STRINGIFY(x)
#define WHERE   __FILE__ ":" TOSTRING(__LINE__)

namespace spelprog2 {

const double DOUBLE_PI = 3.141592653589793238462643383279502884197;
const float FLOAT_PI = float(DOUBLE_PI);
const Ogre::Real OGRE_PI = Ogre::Real(DOUBLE_PI);

typedef Ogre::Exception Exception;

class LogStream {
    typedef boost::shared_ptr<Ogre::Log> LogPtr;
    LogPtr log;
public:
    LogStream() : log() { }
    LogStream(const Ogre::String & filename) : log(new Ogre::Log(filename)) { }

    void rebind(const Ogre::String & filename)
    {
        log.reset(new Ogre::Log(filename));
    }

    template <typename T>
    LogStream & operator << (const T & v)
    {
        if (log) {
            Ogre::Log::Stream::Flush f;
            log->stream() << v << f;
        }
        return *this;
    }
};

extern LogStream gamelog;

}; //namespace spelprog2

#endif